Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[톰캣 구현하기 3, 4단계] 루카(백경환) 미션 제출합니다. #489

Merged
merged 22 commits into from
Sep 13, 2023

Conversation

dooboocookie
Copy link

안녕하세요 25..............

아직 테스트 보완이 필요한 상황이긴 한데요. 리뷰 적용과 같이 테스트도 보완하겠습니다.

  1. 요구사항 정리와 그를 반영하는 테스트
  2. 쓰레드 관련 테스트

그리고 전체적인 구성도는 다음과 같습니다!!
image

1-25 2

다음 리뷰에는 요청 흐름에 대해서도 올려보겠습니다!!
잘부탁드립니다!!

Copy link

@LJW25 LJW25 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요 루카, 이오입니다! 🐕‍🦺🐩
3, 4단계 구현하느라 수고 많으셨습니다. 👏

구성도도 그려주셔서 이해하는데 도움이 되었어요👍
몇가지 궁금한 것도 있고, 오류로 보이는 부분도 있어서 리뷰 남겼으니 확인부탁드립니다. 😁
오류는 아니지만 컨벤션(공백, 접근제어자 등)이 지켜지지 않은 부분은 #컨벤션으로 남겨놓았는데 참고만 해주시고 반영은 안하셔도 됩니다ㅎㅎ

이해가 가지 않는 리뷰가 있다면 DM 주세요.
리팩토링 화이팅❗️❗️

doPost(request, response);
return;
}
response.setStatusCode(METHOD_NOT_ALLOWED);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

405 에러까지 처리하셨네요 👍👍

Comment on lines 9 to 12
@Override
protected void doPost(final Request request, final Response response) {
response.responseNotFound();
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

405 에러를 만드셨는데, 해당 상황을 404로 처리하신 이유가 있을까요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

헉 해당 부분은 실수 입니다. 수정하겠습니다.

Comment on lines 155 to 160
public void redirect(final String path) {
this.statusLine.setStatusCode(FOUND);
final Headers redirectHeaders = new Headers();
redirectHeaders.addHeader(LOCATION, path);
this.headers = redirectHeaders;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

redirect 메소드에서 setStatusCode(FOUND)를 수행하는 이유가 있으실까요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

질문의 의도를 제대로 파악하지 못했습니다!! ㅠㅠㅠㅠ
그래도 제가 최대한 이해한대로 말씀드리면,
이 리다이렉트 메서드는 3xx대의 응답 코드와 Location헤더를 같이 내려주서 path로 준 요청으로 리다이렉트 하는 응답으로 세팅하는 역할을 합니다!!
현재는 요구사항에선 FOUND 응답 상태로 내려가라고 되어있어서 이렇게 진행했습니아!!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앗 제가 너무 생략하고 말씀드렸군요!
저는 redirect 라는 메소드가 redirect 헤더를 추가해주는 것뿐 아닌, 상태코드를 수정하는 것이 해당 메소드의 책임이 맞을까 하는 방향에서 드린 질문이었습니다.
혼동을 드려 죄송합니다. 🥲

}

public Connector(final int port, final int acceptCount, final int maxThreads) {
int coreThreadCount = Runtime.getRuntime().availableProcessors() * 2;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#컨벤션 이 변수도 final 붙일 수 있을것같아요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했습니다!!

Comment on lines +13 to +18
final String account = request.getParameter("account")
.orElseThrow(() -> new IllegalArgumentException("계정 입력이 잘못되었습니다."));
final String password = request.getParameter("password")
.orElseThrow(() -> new IllegalArgumentException("비밀번호 입력이 잘못되었습니다."));
final String email = request.getParameter("email")
.orElseThrow(() -> new IllegalArgumentException("이메일 입력이 잘못되었습니다."));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

꼼꼼한 예외처리 👍
LoginController에서는 다르게 처리하신 이유가 있으실까요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

        final Optional<User> maybeUser = InMemoryUserRepository.findByAccount(account.get());
        if (maybeUser.isEmpty()) {
            response.setStatusCode(UNAUTHORIZED);
            response.writeStaticResource("/401.html");
            return;
        }
        final User findUser = maybeUser.get();
        final Optional<String> password = request.getParameter("password");
        if (password.isEmpty() || !findUser.checkPassword(password.get())) {
            response.setStatusCode(UNAUTHORIZED);
            response.writeStaticResource("/401.html");
            return;
        }

LoginController는 해당 파라미터가 있냐 없냐에 따라서 이 인증 처리의 어떻게 분기 처리할지 갈리게 되므로 그 자체를 판단하기 위해서 Optional 값이 존재하는지 확인합니다.

하지만 위의 회원가입에서는 그 입력값이 들어오지 않았던 것이므로 예외처리를 하게됩니다.

만약 스프링으로 옮긴다면
LoginController에서 리퀘스트 바디를 바인딩하다 생긴 에러는 익셉션 핸들러에 의해서 401응답을 내려주는 과정을 거쳤을 것 같습니다

assertAll(() -> {
assertThat(actual).contains("HTTP/1.1 200 OK");
assertThat(actual).contains("Content-Type: text/html;charset=utf-8");
//assertThat(actual).contains("Content-Length: 5564");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#컨벤션 여기도 안쓰이는 주석이 있어요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제거하겠습니다!

Comment on lines 14 to 17
//given
final String requestUriValue = "/path?a=1&b=2";
//when
RequestUri requestUri = RequestUri.from(requestUriValue);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#컨벤션 given과 when 사이에 공백이 빠졌어요!
그리고 when에서도 final 을 붙일 수 있을 것 같습니다.

다른 테스트에서도 when에 final 이 없는 경우가 많던데, final 을 사용할거라면 통일해서 모두 붙여주는건 어떨까요? (꼭 반영하실 필요는 없어요!)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

꼼꼼한 리뷰 정말 감사합니다..
이런 부분을 신경쓰면서했어야는데 ㅠㅠ

Comment on lines +19 to +23
//then
assertSoftly(softAssertions -> {
softAssertions.assertThat(requestUri.getPath()).isEqualTo("/path");
softAssertions.assertThat(requestUri.getQueryString()).isEqualTo("a=1&b=2");
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다른 테스트에서는 assertAll을 사용하셨는데 여기서만 assertSoftly를 사용하신 이유가 있을까요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

원래는 assertSoftly를 선호하는 편입니다!
이 메서드가 어떤 지점에서 에러가 낫는지 추적하기 훨씬 좋더라구요!! 제가 급하게 테스트를 짜다보니 다르게 적용한 것 같은데 전부 일치시키겠습니다!!

Comment on lines 162 to 172
public void responseUnauthorized() {
this.statusLine.setStatusCode(UNAUTHORIZED);
this.headers = new Headers();
this.body = "";
}

public void responseNotFound() {
this.statusLine.setStatusCode(NOT_FOUND);
this.headers = new Headers();
this.body = "";
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

401, 404 오류가 발생한 경우에 응답 html 페이지는 왜 내려주지 않나요? (진짜 궁금해서 드리는 질문🤔)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어... 실수 입니다...
제가 해당 에러에 응답해줘야될 에러페이지가 있다는 사실을 망각했습니다.
Rest API로 착각해서 그에 대한 응답을 내려줬던 것입니다.
그리고 특정 응답을 세팅하는 메서드가 굳이 필요한 것 같지 않아보이므로 제거하도록하겠습니다.

@@ -3,9 +3,11 @@
public enum StatusCode {

OK(200, "OK"),
CREATED(201, "CREATED"),
FOUND(302, "FOUND"),
UNAUTHORIZED(401, "UNAUTHORIZED"),
NOT_FOUND(404, "NOT FOUND"),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

남길곳이 애매해서 여기에 남깁니다!

현재 잘못된 path를 입력할 경우 404 오류가 발생하지 않고, 그냥 알수없는 예외로 처리되는 것 같아요!
미션 요구사항은 아니었기 때문에 상관은 없지만, 혹시 의도하신 바일까요?

image

Copy link
Author

@dooboocookie dooboocookie Sep 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    public static Controller getController(final Request request) {
        final String path = request.getRequestLine().getRequestPath();
        if (CONTROLLER_MAP.containsKey(path)) {
            return CONTROLLER_MAP.get(path);
        }
        return STATIC_RESOURCE_CONTROLLER;
    }

컨트롤러 매퍼에서 컨트롤러를 조회할 때 절차(우선순위)를 줘서 처리해보았습니다.

  1. 먼저 패스가 매핑되었는지 확인한다.
  2. 매핑이 안된 패스는 정적 파일에서 찾는다.
  3. 정적 파일에 존재하지 않으면 404응답하도록 한다.

@sonarcloud
Copy link

sonarcloud bot commented Sep 12, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

0.0% 0.0% Coverage
0.0% 0.0% Duplication

warning The version of Java (11.0.20.1) you have used to run this analysis is deprecated and we will stop accepting it soon. Please update to at least Java 17.
Read more here

@dooboocookie
Copy link
Author

안녕하세요 이오!!
정말 꼼꼼한 리뷰 감사합니다!
덕분에 세세한 부분까지 잘 인지하면서 수정할 수 있었습니다!!

LJW25

This comment was marked as duplicate.

Copy link

@LJW25 LJW25 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요 루카!

자잘한 수정 요청이 많았는데 잘 반영해주셔서 감사합니다 :)
redirect 관련해서 추가 코멘트 남겼어요. 처음 질문에서 너무 생략하고 말씀드려 죄송해요 😂
리팩토링 너무너무 수고하셨습니다.
루카 덕분에 리뷰하면서 많이 배운것 같아요.

다음 미션도 화이팅 하세요!! 😆

@LJW25 LJW25 merged commit 5274c22 into woowacourse:dooboocookie Sep 13, 2023
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants